from flask import Flask, render_template
from flask_socketio import SocketIO
import threading
import time
from futu import *

app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='threading')

quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111)

# codes = ['HK.02616', 'US.AAPL']  # 订阅的股票
codes = ['HK.02616', 'HK.09888', 'HK.03858','HK.06628', 'HK.00489', 'HK.00434', 'HK.00189','HK.01061','HK.01611','HK.01419']

class StockQuoteTest(StockQuoteHandlerBase):
    def on_recv_rsp(self, rsp_pb):
        ret_code, data = super(StockQuoteTest, self).on_recv_rsp(rsp_pb)
        if ret_code != RET_OK:
            print("StockQuoteTest error:", data)
            return RET_ERROR, data

        fields = [
            'data_date', 'data_time', 'last_price', 'open_price', 'high_price',
            'low_price', 'prev_close_price', 'volume', 'turnover',
            'turnover_rate', 'amplitude', 'suspension', 'listing_date', 'price_spread'
        ]

        for idx, row in data.iterrows():
            stock_info = {field: row.get(field, '') for field in fields}
            stock_info['stock_code'] = row['code'] if 'code' in row else 'UNKNOWN'
            stock_info['stock_name'] = row.get('name', stock_info['stock_code'])
            socketio.start_background_task(socketio.emit, 'quote_update', stock_info, namespace='/')

        return RET_OK, data

handler = StockQuoteTest()
quote_ctx.set_handler(handler)

# 订阅股票实时行情
ret, data = quote_ctx.subscribe(codes, [SubType.QUOTE])
if ret != RET_OK:
    print("订阅失败:", data)

@app.route('/')
def index():
    return render_template('index.html')

def futu_loop():
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        quote_ctx.close()

if __name__ == '__main__':
    threading.Thread(target=futu_loop, daemon=True).start()
    socketio.run(app, host='0.0.0.0', port=5000, debug=True)
